/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 combat_actor.h

	$Header: /heroes4/combat_actor.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( COMBAT_ACTOR_H_INCLUDED )
#define COMBAT_ACTOR_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "abstract_combat_object.h"
#include "abstract_creature.h"
#include "actor_sequence_ptr.h"
#include "attack_angle.h"
#include "cached_ptr.h"
#include "combat_actor_ptr.h"
#include "creature_ability.h"
#include "creature_stack_ptr.h"
#include "idle_ptr.h"
#include "shared_ptr.h"

class   t_battlefield;
enum	t_combat_actor_action_id;
class	t_combat_actor_model;
class   t_combat_label;
class   t_combat_path;
enum    t_creature_ability;
enum	t_direction;
class   t_threat_footprint;

// ------------------------------------------------------------------------------
// t_combat_actor class
// ------------------------------------------------------------------------------

class t_combat_actor : public t_abstract_combat_object
{
public:
	// Types
	typedef t_combat_actor_action_id	t_action_id;
	typedef t_combat_actor_model		t_model;

	// Constructor/Destructor
	t_combat_actor( t_battlefield* battlefield );
	t_combat_actor( t_battlefield* battlefield, t_cached_ptr< t_model > model_ptr,
	                t_action_id action, t_direction direction );
	virtual ~t_combat_actor();

	// Member functions

	virtual bool				blocks_movement() const;
	virtual void				draw_shadow_to(
									t_uint32				current_time,
									t_screen_rect const &	source_rect,
									t_abstract_bitmap16 &	dest,
									t_screen_point const &	dest_point ) const;
	virtual void				draw_shadow_to(
									t_uint32				current_time,
									t_abstract_bitmap16 &	dest,
									t_screen_point const &	dest_point ) const;
	virtual void				draw_to(
									t_uint32				current_time,
									t_screen_rect const &	source_rect,
									t_abstract_bitmap16 &	dest,
									t_screen_point const &	dest_point ) const;
	virtual void				draw_to(
									t_uint32				current_time,
									t_abstract_bitmap16 &	dest,
									t_screen_point const &	dest_point ) const;
	void                        enable_shadow( bool arg = true );
	t_idle_ptr				    get_animation() const;
	int							get_attack_range() const;
	t_map_point_3d              get_body_center() const;
	int							get_brightness() const;
	t_actor_sequence_cache      get_cache( t_action_id action, t_direction direction ) const;
	t_action_id					get_current_action() const;
	t_direction					get_current_direction() const;
	int							get_current_frame_num() const;
	int							get_frame_count() const;
	int							get_frame_count( t_action_id action ) const;
	int							get_frames_per_second() const;
	int							get_frames_per_second( t_action_id action ) const;
	virtual int					get_footprint_size() const;
	virtual int					get_height() const;
	int							get_hue_delta() const;
	int							get_key_frame( t_action_id action ) const;
	t_map_point_3d				get_missile_offset() const;
	t_model const &				get_model() const;
	int							get_postwalk_distance() const;
	int							get_prewalk_distance() const;
	virtual t_screen_rect		get_rect() const;
	virtual t_screen_rect		get_rect( t_uint32 current_time ) const;
	int							get_saturation() const;
	virtual t_screen_rect		get_shadow_rect() const;
	virtual t_screen_rect		get_shadow_rect( t_uint32 current_time ) const;
	t_map_point_3d              get_spell_origin() const;
	int							get_walk_distance() const;
	bool						has_action( t_action_id action ) const;
	bool						has_action( t_action_id action_id, t_direction direction ) const;
	virtual bool				hit_test( t_uint32			    current_time,
										  t_screen_point const&	point ) const;
	virtual bool				is_animated() const;
	virtual bool				is_permanent() const;
	virtual bool				is_underlay() const;
	virtual bool				needs_redrawing( t_uint32	last_update_time,
												 t_uint32	current_time ) const;
	void						set_animation( t_counted_idle_processor* );
	void						set_color( int hue, int hue_delta, int saturation,
		                                   int brightness );
	void						set_current_action( t_action_id new_action_id, int new_frame_num = 0 );
	void						set_current_direction( t_direction new_direction );
	void						set_current_frame_num( int new_frame_num );
	void						set_model( t_cached_ptr< t_model > model_ptr );
	void						set_saturation( int saturation );
protected:
	// Data members
	typedef t_owned_ptr<t_bitmap_layer> t_image_ptr;

	void			initialize();
	virtual bool	read( t_combat_reader& reader );
	virtual bool	write( t_combat_writer& writer ) const;

	t_idle_ptr						m_animation;
	int								m_brightness;
	t_action_id						m_current_action_id;
	t_direction						m_current_direction;
	int								m_current_frame_num;
	t_image_ptr						m_current_image;
	t_screen_point					m_current_image_offset;
	int								m_hue_delta;
	int								m_hue_target;
	t_cached_ptr< t_model >			m_model_ptr;
	int								m_saturation;
	bool                            m_shadow_enabled;
};

class t_unsaved_combat_actor : public t_combat_actor
{
public:
	t_unsaved_combat_actor( t_battlefield*			battlefield,
							t_cached_ptr< t_model > model_ptr,
							t_action_id action,		t_direction direction );

	virtual t_combat_object_type	get_object_type() const;
	virtual bool					read( t_combat_reader& reader );
	virtual bool					write( t_combat_writer& writer ) const;
};

inline t_unsaved_combat_actor::t_unsaved_combat_actor( t_battlefield*			battlefield,
													   t_cached_ptr< t_model >	model_ptr,
												       t_action_id				action, 
													   t_direction				direction )
					         : t_combat_actor( battlefield, model_ptr, action, direction )
{
}

// ------------------------------------------------------------------------------
// t_combat_actor inline members
// ------------------------------------------------------------------------------

inline void t_combat_actor::enable_shadow( bool arg )
{
	m_shadow_enabled = arg;
}

inline t_idle_ptr t_combat_actor::get_animation() const
{
	return m_animation;
}

inline int t_combat_actor::get_brightness() const
{
	return m_brightness;
}

inline t_combat_actor::t_action_id t_combat_actor::get_current_action() const
{
	return m_current_action_id;
}

inline t_direction t_combat_actor::get_current_direction() const
{
	return m_current_direction;
}

inline int t_combat_actor::get_current_frame_num() const
{
	return m_current_frame_num;
}

inline int t_combat_actor::get_hue_delta() const
{
	return m_hue_delta;
}

inline int t_combat_actor::get_saturation() const
{
	return m_saturation;
}

inline bool t_combat_actor::has_action( t_combat_actor_action_id action ) const
{
	return has_action( action, m_current_direction );
}

#endif // !defined( COMBAT_ACTOR_H_INCLUDED )
